package com.didiglobal.booster.aapt2

import com.android.ide.common.resources.configuration.FolderConfiguration
import com.android.resources.Density
import com.didiglobal.booster.aapt.Configuration.ScreenType.Companion.DENSITY_ANY
import com.didiglobal.booster.aapt.Configuration.ScreenType.Companion.DENSITY_DEFAULT
import com.didiglobal.booster.aapt.Configuration.ScreenType.Companion.DENSITY_NONE
import com.didiglobal.booster.aapt2.legacy.ResourcesInternalLegacy
import java.io.File
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

class Aapt2ParserTest {

    @Test
    fun `parse resources generated by 3_1_0`() {
        File(javaClass.getResource("3.1.0").file).listFiles { dir, file ->
            file.endsWith(".flat")
        }.forEach { res ->
            javaClass.getResourceAsStream("${res.parentFile.name}/${res.name}").use { input ->
                val header = BinaryParser(input).use { parser ->
                    val entryType = parser.readInt()
                    val entryLength = parser.readLong()
                    parser.parse {
                        ResourcesInternalLegacy.CompiledFileLegacy.parseFrom(parser.readBytes(entryLength.toInt()))
                    }
                }

                assertNotNull(header)
                assertEquals(res.name.substringBefore('_').substringBefore('-') + "/" + res.name.substringBefore('.').substringAfter('_'), header.resourceName)

                val config = header.config.data.newInput().use {
                    BinaryParser(it).use { parser ->
                        parser.parseConfiguration()
                    }
                }
                assertNotNull(config)

                val density = FolderConfiguration.getConfigForFolder(res.name.substringBefore('_')).densityQualifier.let {
                    when (it.value) {
                        null -> DENSITY_DEFAULT
                        Density.ANYDPI -> DENSITY_ANY
                        Density.NODPI -> DENSITY_NONE
                        else -> it.value.dpiValue.toShort()
                    }
                }
                assertEquals(density, config.screenType.density)
            }
        }
    }

    @Test
    fun `parse flat generated by 3_2_0`() {
        assertAapt2ContainerParsing("3.2.0")
    }

    @Test
    fun `parse flat generated by 3_2_1`() {
        assertAapt2ContainerParsing("3.2.1")
    }

    @Test
    fun `parse flat generated by 3_3_0`() {
        assertAapt2ContainerParsing("3.3.0")
    }

    @Test
    fun `parse flat generated by 3_3_1`() {
        assertAapt2ContainerParsing("3.3.1")
    }

    @Test
    fun `parse flat generated by 3_3_2`() {
        assertAapt2ContainerParsing("3.3.2")
    }

    @Test
    fun `parse flat generated by 3_4_0`() {
        assertAapt2ContainerParsing("3.4.0")
    }

    @Test
    fun `parse flat generated by 3_4_1`() {
        assertAapt2ContainerParsing("3.4.1")
    }

    fun assertAapt2ContainerParsing(version: String) {
        File(javaClass.getResource(version).file).listFiles { dir, file ->
            file.endsWith(".flat")
        }.forEach { flat ->
            assertTrue(flat.exists())

            val metadata = flat.metadata
            assertNotNull(metadata)

            val container = BinaryParser(flat).use { parser ->
                parser.parseAapt2Container()
            }
            assertEquals(container.header.count, container.entries.size)

            container.entries.map {
                it as Aapt2Container.ResFile
            }.forEach { res ->
                assertNotNull(res)
            }
        }
    }

}
